import 'terms.dart';

final basicTermsList1 = [
  Terms.sacrificeBackSacrifice.desc,
  Terms.captureKo.desc,
  Terms.ko.desc,
  Terms.makeEye.desc,
  Terms.doubleAtari.desc,
  Terms.doubleTiger.desc,
];

final basicTermsList2 = [
  Terms.cutAtari.desc,
  Terms.crushCut.desc,
  Terms.atariTurn.desc,
  Terms.atari.desc,
  Terms.cut.desc,
  // Terms.sacrifice.desc,
];

/// 基础术语判定
String judgeBasicTerms(Board board, ChessStep chessStep) {
  Terms terms = Terms.none;
  var lastStep = board.lastOrderedStep;
  if (chessStep.isPass) {
    return Terms.pass.desc;
  }
  int airCount = 0;
  if (!lastStep!.isPass) {
    airCount = board.airCount(lastStep);
  }
  // printInfo('deadList:${lastStep.deadList}');
  if (lastStep.deadList.isNotEmpty) {
    int deadCount = lastStep.deadList.length;
    if (deadCount == 1) {
      /// 提完子,自己只有1口气了,认为是劫
      if (airCount == 1) {
        terms = Terms.ko;
      } else {
        terms = Terms.capture; // 存⼊基础术语盒⼦
        /// 同时满足提、做劫：提劫
        if (isMakeEye(board, chessStep) && airCount == 1) {
          terms = Terms.captureKo;
        } else {
          return '提$deadCount子';
        }
      }
    } else {
      /// 打几还一
      if (airCount == 1) {
        if (deadCount >= 4) {
          terms = Terms.multiStrikePayback;
        } else {
          return '打${numberToChinese(deadCount)}还一';
        }
      } else {
        // terms = Terms.capture;
        return '提$deadCount子';
      }
    }
  } else {
    /// 打吃
    bool isDc = false;
    int dcCount = 0;
    var nearList = getNearChess(board, chessStep, mode: ColorMode.different);
    printInfo('nearList:$nearList');
    List<ChessStep> dcList = List.empty(growable: true);
    for (var it in nearList) {
      if (board.airCount(it) == 1) {
        dcCount++;
        isDc = true;
        dcList.add(it);
      }
    }
    if (isDc) {
      // printInfo('dcCount:$dcCount');
      // 双打
      if (dcCount == 2) {
        ChessStep dcStep1 = dcList.first;
        ChessStep dcStep2 = dcList.last;
        List<ChessStep> nearList1 =
            getNearChess(board, dcStep1, mode: ColorMode.same);
        List<ChessStep> nearList2 =
            getNearChess(board, dcStep2, mode: ColorMode.same);
        if (nearList1.any(
            (value) => nearList2.contains(value) && value.bw == dcStep1.bw)) {
          if (isBreak(board, chessStep)) {
            terms = Terms.cutAtari;
          } else {
            terms = Terms.atari;
          }
        } else {
          terms = Terms.doubleAtari;
        }
      } else {
        // 扑
        if (airCount == 1) {
          terms = Terms.sacrifice;
          // 倒扑
          // 先判断当前子周围是否有同颜色的子
          var list = getNearChess(board, chessStep, mode: ColorMode.same);
          printInfo('list:$list');
          // 如果没有,说明扑的子数量<2,因为当前子的气为1,所以对方的棋子肯定>2
          if (list.isEmpty) {
            var s5List = sCount(board, chessStep, 2, true);
            var s5 = s5List.length;
            for (var it in s5List) {
              if (isOneLineFromStep(it)) {
                s5 = s5 + 1;
              }
            }
            if (s5 >= 2) {
              return Terms.sacrificeBackSacrifice.desc;
            }
          }
        } else {
          // 打吃,存⼊基础术语盒⼦
          terms = Terms.atari;
          int oppositeCount = 0; // 对方棋子数
          int selfCount = 0; // 己方棋子数
          List<ChessStep> selfStepList = [];
          List<ChessStep> oppositeStepList = [];
          final nonZeroSteps = getNonZeroChessSteps(board);
          calculate(s) {
            oppositeCount = 0;
            selfCount = 0;
            selfStepList.clear();
            oppositeStepList.clear();

            for (final step in nonZeroSteps) {
              final distance = distanceSquared(chessStep, step.x, step.y);
              // printInfo('distance:$distance');
              if (distance == s) {
                if (step.bw != chessStep.bw) {
                  oppositeCount++;
                  oppositeStepList.add(step);
                } else {
                  selfCount++;
                  selfStepList.add(step);
                }
              }
            }
          }

          var commonTerms = '';
          for (int s = 1; s < 3; s++) {
            calculate(s);

            /// 常用术语
            commonTerms = judgeCommonTerms(s, oppositeCount, selfCount,
                selfStepList: selfStepList,
                oppositeStepList: oppositeStepList,
                board: board,
                chessStep: chessStep,
                descCoordinates: calculateDirection(chessStep.toGtp()));
            printInfo('常用术语:$commonTerms');
            if (commonTerms.isNotEmpty) {
              break;
            }
          }

          if (commonTerms.contains(Terms.stick.desc)) {
            return Terms.stick.desc;
          }
          // 同时满足打吃、断
          if (isBreak(board, chessStep)) {
            terms = Terms.cutAtari;
          }
        }
      }
    } else {
      if (isBreak(board, chessStep)) {
        // 断
        if (backTerms(2, board) == Terms.crush.desc) {
          // 同时满足前2手是冲，当前手是断，而且这2手棋在对角线上
          terms = Terms.crushCut;
        } else {
          terms = Terms.cut;
        }
      } else if (isMakeEye(board, chessStep)) {
        if (airCount == 1) {
          // 做劫
          terms = Terms.makeKo;
        } else {
          terms = Terms.makeEye;
        }
      } else {
        // 虎
        // 先判断双虎
        int tigerType = isDoubleTiger(board, chessStep);
        if (tigerType == 1) {
          terms = Terms.doubleTiger;
        } else if (tigerType == 2) {
          terms = Terms.tiger;
        }
      }
    }
  }
  return terms.desc;
}
